#pragma once
#include "Hread.h"


typedef struct _OBJECT_TYPE_INITIALIZER
{
	/* 0x0000 */ unsigned short Length;
	union
	{
		/* 0x0002 */ unsigned char ObjectTypeFlags;
		struct /* bitfield */
		{
			/* 0x0002 */ unsigned char CaseInsensitive : 1; /* bit position: 0 */
			/* 0x0002 */ unsigned char UnnamedObjectsOnly : 1; /* bit position: 1 */
			/* 0x0002 */ unsigned char UseDefaultObject : 1; /* bit position: 2 */
			/* 0x0002 */ unsigned char SecurityRequired : 1; /* bit position: 3 */
			/* 0x0002 */ unsigned char MaintainHandleCount : 1; /* bit position: 4 */
			/* 0x0002 */ unsigned char MaintainTypeList : 1; /* bit position: 5 */
			/* 0x0002 */ unsigned char SupportsObjectCallbacks : 1; /* bit position: 6 */
		}; /* bitfield */
	}; /* size: 0x0001 */
	/* 0x0004 */ unsigned long ObjectTypeCode;
	/* 0x0008 */ unsigned long InvalidAttributes;
	/* 0x000c */ struct _GENERIC_MAPPING GenericMapping;
	/* 0x001c */ unsigned long ValidAccessMask;
	/* 0x0020 */ unsigned long RetainAccess;
	/* 0x0024 */ enum _POOL_TYPE PoolType;
	/* 0x0028 */ unsigned long DefaultPagedPoolCharge;
	/* 0x002c */ unsigned long DefaultNonPagedPoolCharge;
	/* 0x0030 */ void* DumpProcedure /* function */;
	/* 0x0038 */ void* OpenProcedure /* function */;
	/* 0x0040 */ void* CloseProcedure /* function */;
	/* 0x0048 */ void* DeleteProcedure /* function */;
	/* 0x0050 */ void* ParseProcedure /* function */;
	/* 0x0058 */ void* SecurityProcedure /* function */;
	/* 0x0060 */ void* QueryNameProcedure /* function */;
	/* 0x0068 */ void* OkayToCloseProcedure /* function */;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER; /* size: 0x0070 */

typedef struct _EX_PUSH_LOCK
{
	union
	{
		struct /* bitfield */
		{
			/* 0x0000 */ unsigned __int64 Locked : 1; /* bit position: 0 */
			/* 0x0000 */ unsigned __int64 Waiting : 1; /* bit position: 1 */
			/* 0x0000 */ unsigned __int64 Waking : 1; /* bit position: 2 */
			/* 0x0000 */ unsigned __int64 MultipleShared : 1; /* bit position: 3 */
			/* 0x0000 */ unsigned __int64 Shared : 60; /* bit position: 4 */
		}; /* bitfield */
		/* 0x0000 */ unsigned __int64 Value;
		/* 0x0000 */ void* Ptr;
	}; /* size: 0x0008 */
} _EX_PUSH_LOCK, *_PEX_PUSH_LOCK; /* size: 0x0008 */

typedef struct _OBJECT_TYPE
{
	/* 0x0000 */ struct _LIST_ENTRY TypeList;
	/* 0x0010 */ struct _UNICODE_STRING Name;
	/* 0x0020 */ void* DefaultObject;
	/* 0x0028 */ unsigned char Index;
	/* 0x002c */ unsigned long TotalNumberOfObjects;
	/* 0x0030 */ unsigned long TotalNumberOfHandles;
	/* 0x0034 */ unsigned long HighWaterNumberOfObjects;
	/* 0x0038 */ unsigned long HighWaterNumberOfHandles;
	/* 0x0040 */ struct _OBJECT_TYPE_INITIALIZER TypeInfo;
	/* 0x00b0 */ struct _EX_PUSH_LOCK TypeLock;
	/* 0x00b8 */ unsigned long Key;
	/* 0x00c0 */ struct _LIST_ENTRY CallbackList;
} OBJECT_TYPE, *POBJECT_TYPE; /* size: 0x00d0 */



typedef struct _OBJECT_CREATE_INFORMATION
{
	ULONG Attributes;
	HANDLE RootDirectory;
	PVOID ParseContext;
	KPROCESSOR_MODE ProbeMode;
	ULONG PagedPoolCharge;
	ULONG NonPagedPoolCharge;
	ULONG SecurityDescriptorCharge;
	PSECURITY_DESCRIPTOR SecurityDescriptor;
	PSECURITY_QUALITY_OF_SERVICE SecurityQos;
	SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;

typedef struct _OBJECT_HEADER
{
	LONG_PTR PointerCount;
	union
	{
		LONG_PTR HandleCount;
		volatile PVOID NextToFree;
	};
	POBJECT_TYPE Type;
	UCHAR NameInfoOffset;
	UCHAR HandleInfoOffset;
	UCHAR QuotaInfoOffset;
	UCHAR Flags;
	union
	{
		POBJECT_CREATE_INFORMATION ObjectCreateInfo;
		PVOID QuotaBlockCharged;
	};
	PSECURITY_DESCRIPTOR SecurityDescriptor;
	QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;


typedef enum _OB_OPEN_REASON
{
	ObCreateHandle,
	ObOpenHandle,
	ObDuplicateHandle,
	ObInheritHandle,
	ObMaxOpenReason
} OB_OPEN_REASON;





#define OBJ_KERNEL_EXCLUSIVE                    0x00010000L
#define OBJ_VALID_KERNEL_ATTRIBUTES             (OBJ_VALID_ATTRIBUTES | OBJ_KERNEL_EXCLUSIVE)
#define CONST_LUID(x1, x2) {x1, x2}
const LUID SeDebugPrivilege = CONST_LUID(SE_DEBUG_PRIVILEGE, 0);

#define ProbeForWriteGenericType(Ptr, Type)                                    \
    do {                                                                       \
        if ((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) ||          \
            (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) { \
            ExRaiseAccessViolation();                                          \
        }                                                                      \
        *(volatile Type *)(Ptr) = *(volatile Type *)(Ptr);                     \
    } while (0)




#define ProbeForWriteHandle(Ptr) ProbeForWriteGenericType(Ptr, HANDLE)




#define OBJECT_TO_OBJECT_HEADER(o)               CONTAINING_RECORD((o), OBJECT_HEADER, Body)










typedef struct _AUX_ACCESS_DATA
{
	PPRIVILEGE_SET PrivilegeSet;
	GENERIC_MAPPING GenericMapping;
	ULONG Reserved;
} AUX_ACCESS_DATA, *PAUX_ACCESS_DATA;
















NTSTATUS NTKERNELAPI SeCreateAccessStateEx(IN PETHREAD Thread,
	IN PEPROCESS Process,
	IN OUT PACCESS_STATE AccessState,
	IN char* AuxData,
	IN ACCESS_MASK Access,
	IN PGENERIC_MAPPING GenericMapping);


VOID NTKERNELAPI SeDeleteAccessState(IN PACCESS_STATE AccessState);

NTSTATUS
NTKERNELAPI
ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
	IN POBJECT_TYPE ObjectType,
	IN KPROCESSOR_MODE AccessMode,
	IN PACCESS_STATE PassedAccessState,
	IN ACCESS_MASK DesiredAccess,
	IN OUT PVOID ParseContext,
	OUT PHANDLE Handle);


NTSTATUS NTKERNELAPI PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
	OUT PEPROCESS *Process OPTIONAL,
	OUT PETHREAD *Thread);
FORCEINLINE ULONG ObpValidateAttributes(IN ULONG Attributes, IN KPROCESSOR_MODE PreviousMode)
{

	if (PreviousMode == KernelMode)
	{

		return Attributes & OBJ_VALID_KERNEL_ATTRIBUTES;
	}

	return (Attributes & OBJ_VALID_ATTRIBUTES) &~(OBJ_KERNEL_HANDLE);

}